package org.wmq.taskschedule.algorithm;

import org.opencv.core.Mat;
import org.opencv.imgproc.Imgproc;
import org.springframework.stereotype.Component;

/**
 * Canny边缘检测器
 * 实现了AlgorithmExecutor抽象类，专注于图像边缘检测功能
 * 不使用父类的type字段
 */
public class CannyEdgeDetector implements AlgorithmExecutor {
    
    // 算法参数
    private int threshold1; // 第一个阈值（低阈值）
    private int threshold2; // 第二个阈值（高阈值）
    private int apertureSize; // Sobel算子的孔径大小
    private boolean l2gradient; // 是否使用L2梯度范数

    /**
     * 默认构造函数
     * 使用常用的默认参数配置
     */
    public CannyEdgeDetector() {
        this(50, 150); // 默认阈值设置
    }

    /**
     * 构造函数，指定边缘检测的阈值
     * @param threshold1 低阈值
     * @param threshold2 高阈值
     */
    public CannyEdgeDetector(int threshold1, int threshold2) {
        this(threshold1, threshold2, 3, false);
    }

    /**
     * 完整参数的构造函数
     * @param threshold1 低阈值
     * @param threshold2 高阈值
     * @param apertureSize Sobel算子孔径大小
     * @param l2gradient 是否使用L2梯度范数
     */
    public CannyEdgeDetector(int threshold1, int threshold2, int apertureSize, boolean l2gradient) {
        this.threshold1 = threshold1;
        this.threshold2 = threshold2;
        this.apertureSize = apertureSize;
        this.l2gradient = l2gradient;
        
        // 设置算法描述，但不使用type字段
    }
    
    /**
     * 执行Canny边缘检测算法
     * @param input 输入的图像矩阵
     * @return 边缘检测结果矩阵
     */
    @Override
    public Mat execute(Mat input) {
        if (input == null || input.empty()) {
            throw new IllegalArgumentException("Input image cannot be null or empty");
        }
        
        Mat output = new Mat();
        
        try {
            // 如果输入不是灰度图，先转换为灰度图
            Mat grayImage = new Mat();
            if (input.channels() > 1) {
                Imgproc.cvtColor(input, grayImage, Imgproc.COLOR_BGR2GRAY);
            } else {
                input.copyTo(grayImage);
            }
            
            // 应用高斯模糊以减少噪声
            Mat blurredImage = new Mat();
            Imgproc.GaussianBlur(grayImage, blurredImage, 
                    new org.opencv.core.Size(5, 5), 1.5);
            
            // 应用Canny边缘检测算法
            Imgproc.Canny(blurredImage, output, 
                    threshold1, threshold2, 
                    apertureSize, l2gradient);
            
            // 释放临时资源
            grayImage.release();
            blurredImage.release();
            
        } catch (Exception e) {
            throw new RuntimeException("Failed to execute Canny edge detection", e);
        }
        
        return output;
    }
    
    // 参数的getter和setter方法
    public int getThreshold1() {
        return threshold1;
    }
    
    public void setThreshold1(int threshold1) {
        this.threshold1 = threshold1;
    }
    
    public int getThreshold2() {
        return threshold2;
    }
    
    public void setThreshold2(int threshold2) {
        this.threshold2 = threshold2;
    }
    
    public int getApertureSize() {
        return apertureSize;
    }
    
    public void setApertureSize(int apertureSize) {
        this.apertureSize = apertureSize;
    }
    
    public boolean isL2gradient() {
        return l2gradient;
    }
    
    public void setL2gradient(boolean l2gradient) {
        this.l2gradient = l2gradient;
    }
}